import _ from 'lodash';
import MathUtil from '@src/util/math';
import * as FormUtil from '@src/component/form/util';
import { isEmpty } from '@src/util/type'
import { FORM_FIELD_TEXT_MAX_LENGTH, FORM_FIELD_TEXTAREA_MAX_LENGTH } from '@src/model/const/Number.ts';
import { CURRENCY_SUFFIX, allAmountFieldNameList } from '@src/util/currency';

import * as FieldValidateApi from '@src/api/FieldValidateApi.ts';
/* enum */
import TableNameEnum from '@model/enum/TableNameEnum.ts';
import { ProductTypeFieldNameMappingEnum } from '@model/enum/FieldMappingEnum.ts'
/* service */
import { isQualityRuleTimeFieldEmpty, isQualityRuleTimeFieldQualityTimeNumberEmpty, isQualityRuleTimeFieldQualityTimeTypeEmpty } from '@service/QualityRuleService.ts'

// 单行最大长度
export const SINGLE_LINE_MAX_LEN = FORM_FIELD_TEXT_MAX_LENGTH;
// 多行最大长度
export const MULTI_LINE_MAX_LEN = FORM_FIELD_TEXTAREA_MAX_LENGTH;
// 电话
export const TEL_REG = /^(((0\d{2,3}-{0,1})?\d{7,8})|(\d{6}))$/;
// 手机号
export const PHONE_REG = /^((1[3578496]\d{9})|([+][0-9-]{1,30}))$/;
// 日期格式 yyyy-MM-dd
export const DATE_REG = /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/;
// 日期格式 yyyy-MM-dd HH:mm:ss
export const DATE_SS_REG = /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s{1}(20|21|22|23|[0-1]\d):[0-5]\d(:[0-5]\d)?$/;
// 日期格式 yyyy-MM-dd HH:mm
export const DATE_mm_REG = /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s{1}(20|21|22|23|[0-1]\d):[0-5]\d?$/;
// 日期格式 yyyy-MM
export const DATE_YY_REG = /^[1-9]\d{3}-(0[1-9]|1[0-2])?$/;

// 日期时间格式
export const DATETIME_REG = /^\d{4}-\d{1,2}-\d{1,2}\s\d{2}:\d{2}:\d{2}$/;
// 邮箱格式
export const EMAIL_REG = /^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/;
// 链接格式
export const LINK_REG = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/;
// 产品类型编号格式
export const CATALOGNUM_REG = /^[A-Za-z0-9]+$/;
import i18n from '@src/locales'
import { isValidDate } from 'pub-bbx-utils';
import { message } from '@src/util/message';

// 国际化相关所有校验方法整合

//代码块的执行
import { executeCode } from '@src/component/form/components/FormJsControl/model/index';

/**
 * @des 校验电话号相关
 * @params value { string | number }
 * @params type { number } 1 中国手机号  2 中国固话号 3 12混合校验
 */
export const validatePhone = (value, type = 1)=>{
  // 国际化与产品协商去除电话号码校验
  return true
}

export const fieldValidateMap = {
  customer: FieldValidateApi.fieldRepeatCustomer,
  product: FieldValidateApi.fieldRepeatProduct,
  productTemplate: FieldValidateApi.fieldRepeatProductTemplate,
  productRegister: FieldValidateApi.checkRegisterRepeat,
  contract: FieldValidateApi.fieldRepeatContract,
  projectType: FieldValidateApi.projectTypeCheckRepeat,
  mission: FieldValidateApi.commonTaskCheckRepeat, // 通用任务唯一值校验
  product_menu: FieldValidateApi.productTypeCheckRepeat,
  [TableNameEnum.Task]: FieldValidateApi.fieldRepeatTask,
  [TableNameEnum.TaskReceipt]: FieldValidateApi.fieldRepeatTask,
  [TableNameEnum.TaskCard]: FieldValidateApi.fieldRepeatCard,
  [TableNameEnum.CustomerCard]: FieldValidateApi.cardInfoRepeat,
  [TableNameEnum.ProductCard]: FieldValidateApi.cardInfoRepeat,
  [TableNameEnum.Event]: FieldValidateApi.eventFieldRepeatCheck,
  [TableNameEnum.EventReceipt]: FieldValidateApi.eventFieldRepeatCheck,
  [TableNameEnum.EventCard]: FieldValidateApi.eventCardFieldRepeat,
}

let remoteValidateDebounceFunc = null

const RuleMap = {
  text,
  select,
  textarea,
  code: text,
  number,
  date,
  datetime,
  phone,
  email,
  catalogNum,
  user,
  attachment,
  address,
  link,
  customer: select,
  customerAddress: select,
  linkman: select,
  product: select,
  sparepart: select,
  serviceIterm: select,
  materialVerifyEliminate: select,
  materialReturn: select,
  serviceContent: select,
  serviceType: select,
  tags: select,
  level: select,
  planTime,
  planStartTime,
  planEndTime,
  formula,
  cascader,
  related_task: relatedTask,
  description: textarea,
  receiptAttachment: attachment,
  'related_wiki': relatedTask,
  'related_part': relatedTask,
  related_customers: relatedTask,
  logistics,
  richtext,
  rich_text: richtext,
  serviceProviders: relatedTask,
  serviceProviderQualification: select,
  engineerQualification: select,
  relationForm: relatedTask,
  relationMaterials: select,
  relatedServiceItem: select,
  materialsBill: select,
  subSparePart: select,
  subServiceItem: select,
  subMaterials: select,
  subSucCase: select,
  subCertifications: select,
  tagLabel: select,
  imageDisplay: select,
  connector,
  idcard: text,
  productWarrantyService: select,
  projectCustomer: select,
  projectProduct: select,
  currency,
  expectTime: number,
  costTime: number,
  remainTime: number,
  newFaultLibrary: select,
  serviceRemark: text,
  jsCodeBlock,
  tag,
};

// 远程验证字段是否重复方法
let repeatRemoteValidate = (mode, myField, value, id, changeStatus, resolve, isSample = true, formBuilderComponent = {}, templateId, cardType) => {
  
  const remoteFunc = (value, resolve) => {
    let api = fieldValidateMap[mode];
    let params = { fieldName: myField.fieldName, fieldValue: value, id, cardType};
    if(!myField.isCommon) params.templateId = templateId;
    
    // api不存在
    if (!api) return resolve(null);
    
    changeStatus(true);
    if (mode === 'productRegister') {
      return api({
        fieldList: [{
          displayName: myField.displayName,
          ...params
        }],
        id
      }).then(res => {
        changeStatus(false);
        return resolve(res?.result?.length ? i18n.t('common.util.validator.sthNotAllowRepeat', {data: myField.displayName}) : null)
      })
    }
    return api(params).then(res => {
      changeStatus(false);
      return resolve((res.succ || res.success) ? ((res.data == 1 || res.result == 1) ? i18n.t('common.util.validator.sthNotAllowRepeat', {data: myField.displayName}) : null) : null);
    })
      .catch(err => console.error(err))
  }
  
  if (isSample) {
    let { remoteValidateData } = formBuilderComponent
    let { validateFunc, field } = remoteValidateData
    
    if (!validateFunc) {
      validateFunc = _.debounce(remoteFunc, 500)

      if(field === myField.fieldName) {
        formBuilderComponent.outsideSetRemoteValidateData({
          field: myField.fieldName,
          validateFunc
        })
      }
    }
    
    validateFunc(value, resolve)
    
  } else {
    remoteFunc(value, resolve)
  }

}

/** 单行文本验证，50字以内 */
function text(value, field = {}, origin = {}, mode, changeStatus, isSample = true, formBuilderComponent = {}, cardType){
  let { isRepeat, defaultValueConfig, isLimitWord, limitWordMin, limitWordMax } = field.setting || {};

  // 默认值是否允许修改
  let { isNotModify } = defaultValueConfig || {};
  let notModifyValue = isNotModify == 1 && !!field.defaultValue;

  let validate = new Promise((resolve, reject) => {
    // 先验证限制字数
    if (isLimitWord) {
      if (limitWordMax && value != null && value.toString().length > limitWordMax) {
        return resolve(i18n.t('common.util.validator.maxLengthTip', {max: limitWordMax}));
      }
      if (limitWordMin && value != null && value.toString().length < limitWordMin) {
        return resolve(i18n.t('common.util.validator.minLengthTip', {min: limitWordMin}));
      }
    }
    // 先验证长度
    if(value != null && value.toString().length > SINGLE_LINE_MAX_LEN){
      return resolve(i18n.t('common.util.validator.maxLengthTip', {max: SINGLE_LINE_MAX_LEN}));
    }
    // 允许为空则不继续验证
    if(field.isNull) return resolve(null);
    // 不允许为空
    if(!value || value.toString().trim().length == 0) return resolve(i18n.t('common.placeholder.inputSomething', {data1: field.displayName}));
    resolve(null);
  })
  
  // 不需要校验重复性
  if (!isRepeat || !mode || !value || notModifyValue) return validate;
  
  return new Promise((resolve, reject) => {
    validate.then((res) => {
      res === null 
        ? repeatRemoteValidate(mode, field, value, origin.id, changeStatus, resolve, isSample, formBuilderComponent, origin.templateId, cardType) 
        : resolve(res);
    }).catch(err => {
      console.error('text validate err', err);
    })
  })
}

/** 单选必选验证 */
function select(value, field = {}) {
  return new Promise((resolve, reject) => {
    if (field.isNull) return resolve(null);
    if (value == null || !value.toString().length) return resolve(i18n.t('common.placeholder.selectSomething', {0: field.displayName}));
    resolve(null);
  })
}

/** 连接器必选验证 */
function connector(value, field = {}) {
  return new Promise((resolve, reject) => {
    // if (field.isNull) return resolve(null);
    // if (value == null || !value.toString().length) return resolve(`请添加${field.displayName}`);

    if (!field.isNull && (!value || isEmpty(value))) {
      return resolve(`请添加${field.displayName}`);
    }

    const subFormFieldList = field?.subFormFieldList || field.setting?.subFormFieldList || {};

    let message = '';

    // 校验子字段必填
    for (let i = 0; i < value.length; i++) {
      let fieldValue = value[i];

      let emptyFields = subFormFieldList.filter(f => !f.isNull && _.isEmpty(fieldValue[f.fieldName]) && !FormUtil.isHiddenField(f, fieldValue, subFormFieldList));

      if (emptyFields.length) {
        let emptyFieldText = emptyFields.map(f => f.displayName).join('、');
        message = i18n.t('common.util.validator.subFormTip', {data1: i + 1, data2: emptyFieldText});
        break;
      }
    }

    if (message) return resolve(message);

    resolve(null);
  })
}

// 国际货币
function currency(value, field = {}){
  return new Promise((resolve, reject) => {
    if (field.isNull) return resolve(null);
    if (isEmpty(value) || (!value?.number && value?.number !== 0)) return resolve(i18n.t('common.placeholder.inputSomething', {data1: field.displayName}));
    if (typeof Number(value) !== 'number') return resolve(i18n.t('common.placeholder.inputNumber'));
    resolve(null);
  })
}


/** 多级菜单验证 */
function cascader(value, field = {}){

  return new Promise(resolve => {
    let setting = field.setting || {};
    let maxDeep = setting.maxDeep || 2;
    // if(((field.isNull == 1 && value.length > 0) || field.isNull == 0) && value.length < maxDeep) return resolve(`请补全${field.displayName}`);
    if (field.isNull) return resolve(null);
    if(value == null || !value.toString().length) return resolve(i18n.t('common.placeholder.selectSomething', {0: field.displayName}));
    resolve(null);
  
  });
}

/** 多行文本验证，500字以内 */
function textarea(value, field = {}, origin = {}, mode, changeStatus, isSample = true, formBuilderComponent = {}, cardType) {
  let { isRepeat, defaultValueConfig, isLimitWord, limitWordMin, limitWordMax } = field.setting || {};

  // 默认值是否允许修改
  let { isNotModify } = defaultValueConfig || {};
  let notModifyValue = isNotModify == 1 && !!field.defaultValue;
  
  let validate = new Promise((resolve, reject) => {
    // 先验证限制字数
    if (isLimitWord) {
      if (limitWordMax && value != null && value.toString().length > limitWordMax) {
        return resolve(i18n.t('common.util.validator.maxLengthTip', {max: limitWordMax}));
      }
      if (limitWordMin && value != null && value.toString().length < limitWordMin) {
        return resolve(i18n.t('common.util.validator.minLengthTip', {min: limitWordMin}));
      }
    }
    if (value !== null && value.toString().length > MULTI_LINE_MAX_LEN) {
      return resolve(i18n.t('common.util.validator.maxLengthTip', {max: MULTI_LINE_MAX_LEN}));
    }
    if (field.isNull === 1) return resolve(null);
    if (value == null || value.toString().length == 0 || value.toString().trim().length == 0) return resolve(i18n.t('common.placeholder.inputSomething', {data1: field.displayName}));
    resolve(null);
  });

  // 不需要校验重复性
  if (!isRepeat || !mode || !value || notModifyValue) return validate;

  return new Promise((resolve, reject) => {
    validate.then((res) => {
      res === null ? repeatRemoteValidate(mode, field, value, origin.id, changeStatus, resolve, isSample, formBuilderComponent, origin.templateId, cardType) : resolve(res);
    }).catch(err => {
      console.error('textarea validate err', err);
    })
  })
}

// 验证电话手机格式
function phone(value, field = {}, origin = {}, mode, changeStatus, isSample = true, formBuilderComponent = {}, cardType) {
  let { isRepeat, phoneFormatChecks = true } = field.setting || {};
  let validate = new Promise(resolve => {
    if(!phoneFormatChecks) return resolve(null);
    if((field.isNull || field.isNullRelationFields?.length) && !value) return resolve(null);
    if(value == null || !value.toString().length) return resolve(i18n.t('common.placeholder.inputSomething', {data1: field.displayName}));
    if(field?.onlyAllowReg) {
      if(field.onlyAllowReg.test(value))return resolve(null);
    }
    if (!validatePhone(value, 3)) return resolve(i18n.t('common.util.validator.phoneTip'));
    resolve(null);
  });

  // 不需要校验重复性
  if (!isRepeat || !mode || !value) return validate;

  return new Promise((resolve, reject) => {
    validate.then((res) => {
      res === null ? repeatRemoteValidate(mode, field, value, origin.id, changeStatus, resolve, isSample, formBuilderComponent, origin.templateId, cardType) : resolve(res);
    }).catch(err => {
      console.error('phone validate err', err);
    })
  })
}

function email(value, field = {}) {
  return new Promise(resolve => {
    if((field.isNull || field.isNullRelationFields?.length) && !value) return resolve(null);
    if(value == null || !value.toString().length) return resolve(i18n.t('common.placeholder.inputSomething', {data1: field.displayName}));
    if (!EMAIL_REG.test(value)) return resolve(i18n.t('common.util.validator.emailTip'));
    resolve(null);
  });
}

function richtext(value, field = {}) {
  return new Promise(resolve => {
    if(field.isNull && !value) return resolve(null);
    if(value == null || !value.toString().length) return resolve(i18n.t('common.placeholder.inputSomething', {data1: field.displayName}));
    resolve(null);
  });
}

function catalogNum(value, field = {}){
  return new Promise(resolve => {
    if(field.isNull && !value) return resolve(null);
    if(value.indexOf('/') > -1) return resolve(i18n.t('common.util.validator.catalogNumTip'));
    if(value == null || !value.toString().length) return resolve(i18n.t('common.placeholder.inputSomething', {data1: field.displayName}));
    resolve(null);
  });
}

function qualityTime(value, field) {
  return new Promise(resolve => {
    if (
      field.isNull 
      && !isQualityRuleTimeFieldQualityTimeNumberEmpty(value) 
      && isQualityRuleTimeFieldQualityTimeTypeEmpty(value)
    ) {
      return resolve(i18n.t('common.util.validator.qualityTimeTip', {data: field.displayName}))
    }
    
    if (
      field.isNull 
      && isQualityRuleTimeFieldQualityTimeNumberEmpty(value) 
      && !isQualityRuleTimeFieldQualityTimeTypeEmpty(value)
    ) {
      return resolve(i18n.t('common.placeholder.inputSomething', {data1: field.displayName}))
    }
    
    if (field.isNull) return resolve(null)
    if (isQualityRuleTimeFieldQualityTimeNumberEmpty(value)) return resolve(i18n.t('common.placeholder.inputSomething', {data1: field.displayName}))
    if (isQualityRuleTimeFieldQualityTimeTypeEmpty(value)) return resolve(i18n.t('common.util.validator.qualityTimeTip', {data: field.displayName}))
    
    resolve(null)
  });
}

function date(value, field = {}) {
  return new Promise(resolve => {
    if (!value && field.isNull === 1) return resolve(null);
    if (!value || !value.toString().length) return resolve(i18n.t('common.placeholder.selectSomething', {0: field.displayName}));
    if(!value && isValidDate(value)) {
      // 无法解析时间时间格式不正确
      return resolve(i18n.t('common.util.validator.dateTip'));
    }
    
    resolve(null);
  });
}

function datetime(value, field = {}) {
  return date(value, field) // 时间统一传递完整时间，统一使用date验证，回显时再根据显示进行format
}

function planTime(value, field = {}) {
  return date(value, field) // 时间统一传递完整时间，统一使用date验证，回显时再根据显示进行format
  // return new Promise(resolve => {
  //   if (field.isNull === 1) return resolve(null);
  //   if (!value || !value.toString().length) return resolve(i18n.t('common.placeholder.selectSomething', {0: field.displayName}));
  //   let REG = field.setting.dateType == 'date' ? DATE_REG : DATETIME_REG;
  //   if (!REG.test(value)) return resolve(i18n.t('common.util.validator.dateTip'));
  //   resolve(null);
  // });
}
function planStartTime(value, field = {}) {
  return date(value, field) // 时间统一传递完整时间，统一使用date验证，回显时再根据显示进行format
  // return new Promise(resolve => {
  //   if (field.isNull === 1) return resolve(null);
  //   if (!value || !value.toString().length) return resolve(i18n.t('common.placeholder.selectSomething', {0: field.displayName}));
  //   let REG = field.setting.dateType == 'date' ? DATE_REG : DATETIME_REG;
  //   if (!REG.test(value)) return resolve(i18n.t('common.util.validator.dateTip'));
  //   resolve(null);
  // });
}
function planEndTime(value, field = {}) {
  return date(value, field) // 时间统一传递完整时间，统一使用date验证，回显时再根据显示进行format
  // return new Promise(resolve => {
  //   if (field.isNull === 1) return resolve(null);
  //   if (!value || !value.toString().length) return resolve(i18n.t('common.placeholder.selectSomething', {0: field.displayName}));
  //   let REG = field.setting.dateType == 'date' ? DATE_REG : DATETIME_REG;
  //   if (!REG.test(value)) return resolve(i18n.t('common.util.validator.dateTip'));
  //   resolve(null);
  // });
}

function number(value, field = {}, origin = {}, mode, changeStatus, isSample = true, formBuilderComponent = {}) {
  let { decimalConfig, limitConig, defaultValueConfig, isRepeat } = field.setting || {};
  // 默认值是否允许修改
  let { isNotModify } = defaultValueConfig || {};
  let notModifyValue = isNotModify == 1 && !!field.defaultValue;
  
  
  let validate = new Promise(resolve => {
    // 默认值且不允许修改时 不做校验
    if (notModifyValue) return resolve(null);
    
    // 校验小数位数
    if (typeof decimalConfig === 'object' && !(isEmpty(decimalConfig))) {
      let { digit, isLimit } = decimalConfig;
      let decimal = MathUtil.decimalNumber(value);
      
      // 勾选小数位数且设置了小数位数
      if (isLimit == 1 && digit != '' && decimal > Number(digit)) {
        let errMsg = digit == 0 ? i18n.t('common.util.validator.numberTip1') : i18n.t('common.util.validator.numberTip2', {count: digit});
        return resolve(errMsg);
      }
    }
      
    // 校验数值范围
    if (typeof limitConig == 'object' && value) {
      let { isLimit, type, max, min } = limitConig;

      // 勾选限制数值输入范围
      if (isLimit == 1) {
        if (max || min) {
          let minValue = min ? (type == 1 ? min : origin[min]) : '';
          let maxValue = max ? (type == 1 ? max : origin[max]) : '';

          if (minValue && !maxValue && Number(value) < Number(minValue)) return resolve(i18n.t('common.util.validator.numberTip3', {minValue}));
          if (!minValue && maxValue && Number(value) > Number(maxValue)) return resolve(i18n.t('common.util.validator.numberTip4', {maxValue}));
          if (minValue && maxValue && (Number(value) > Number(maxValue) || Number(value) < Number(minValue))) return resolve(i18n.t('common.util.validator.numberTip5', {minValue, maxValue}));
        }
      }
    }

    if (field.isNull === 1) return resolve(null);
    if (!value || !value.toString().length) return resolve(i18n.t('common.placeholder.inputSomething', {data1: field.displayName}));
    if (typeof Number(value) !== 'number') return resolve(i18n.t('common.placeholder.inputNumber'));
    resolve(null);
  });
  
  // 不需要校验重复性
  if (!isRepeat || !mode || !value || notModifyValue) return validate;

  return new Promise((resolve, reject) => {
    validate.then((res) => {
      res === null ? repeatRemoteValidate(mode, field, value, origin.id, changeStatus, resolve, isSample, formBuilderComponent, origin.templateId) : resolve(res);
    }).catch(err => {
      console.error('number validate err', err);
    })
  })
}


function formula(value, field, origin = {}, mode, changeStatus, isSample = true, formBuilderComponent = {}, cardType) {
  let { defaultValueConfig = {}, formula = [] } = field.setting || {};

  // 不允许修改
  let isNotModify = defaultValueConfig?.isNotModify == 1 && formula.length > 0;

  // 校验计算的货币金额的币种是否统一
  let isCurrencyUnified = true;
  let needCheckCurrency = field?.setting?.checkCurrency === 1;
  if (needCheckCurrency) {
    const fieldsList = formBuilderComponent.fields || [];
    const currencyList = (field?.setting?.formula || [])
      .filter(item => !item.isOperator)
      .map(item => {
        const cf = fieldsList.find(f => f.fieldName === item.value);
        
        // 兼容之前formType为number的金额字段
        if( cf?.fieldName && allAmountFieldNameList.includes(cf.fieldName)) return origin[item.value + CURRENCY_SUFFIX] || '';
        if (cf?.formType && cf.formType === 'currency') return origin[item.value]?.currency || '';
        return '';
      })
      .filter(item => item);

    let deduplicationCurrency = Array.from(new Set(currencyList));
    if (deduplicationCurrency && deduplicationCurrency.length > 1) {
      isCurrencyUnified = false;
    }
  }

  return new Promise(resolve => {
    // 空值
    let isEmpty = !value || !value.toString().length;

    if (needCheckCurrency && !isCurrencyUnified) return resolve(i18n.t('common.util.validator.currencyCheckTip'));
    if (field.isNull === 1) return resolve(null);
    if (isNotModify && isEmpty) return resolve(i18n.t('common.util.validator.formulaTip', {name: field.displayName}));
    if (isEmpty) return resolve(i18n.t('common.placeholder.inputSomething', {data1: field.displayName}));
    if (typeof Number(value) !== 'number') return resolve(i18n.t('common.placeholder.inputNumber'));
    resolve(null);
  });
}

function attachment(value, field = {}) {
  return new Promise(resolve => {
    if (field.isNull === 1) return resolve(null);
    if (!value || !value.toString().length) return resolve(i18n.t('common.placeholder.uploadSth', {data: field.displayName}));
    resolve(null);
  });
}

function relatedTask(value, field = {}) {
  return new Promise(resolve => {
    if (field.isNull === 1) return resolve(null);
    if (!Array.isArray(value)) {
      return resolve(i18n.t('common.util.validator.relatedTaskTip', {name: field.displayName}));
    }
    if (value.length <= 0) {
      return resolve(i18n.t('common.placeholder.selectSomething', {0: field.displayName}));
    } 
    resolve(null);
  });
}

function user(value, field = {}) {
  return new Promise(resolve => {
    if (field.isNull === 1) return resolve(null);
    // 判断是否为空值
    let isEmpty = Array.isArray(value) ? (value.length <= 0 || !value[0].userId) : !value?.userId;
    if (field.tableName === 'mission' && Array.isArray(value) && value[0].id)  {
      // 项目管理任务表单兼容处理
      isEmpty = false
    }
    
    if (!value || isEmpty) return resolve(i18n.t('common.placeholder.selectSomething', {0: field.displayName}));
    resolve(null);
  });
}

function address(value, field = {}) {
  return new Promise(resolve => {
    if (field.isNull) return resolve(null);
    if (!value || !value.toString().length) return resolve(i18n.t('common.util.validator.addressTip1', {data: field.displayName}));
    
    
    const { country, province, city, address } = value || {};
    // 之前的校验是!province || !city || !address，最少选到市
    // 接入国际化地址组件后，校验修改一下，中国必须选到市，外国最少选到省
    // 有的地区没有省，有的地区没有市，也就是说只要有省或者有市就校验通过，省市两个都没有就校验不通过。
    const chinaValid = (!province && !city) || !address;
    const foreignValid = !country || !address;
    // 老数据没有country，取不到country就默认中国，存入数据库的是汉字，中国不需要替换，国际化不需要替换！！！！！！
    // 国际化不需要替换！！！！！！国际化不需要替换！！！！！！国际化不需要替换！！！！！！国际化不需要替换！！！！！！
    const valid = !country || country === '中国' ? chinaValid : foreignValid
    if (valid) {
      return resolve(i18n.t('common.base.isRequire'));
    }
    if (address.length > SINGLE_LINE_MAX_LEN) return resolve(i18n.t('common.util.validator.addressTip2', {max: SINGLE_LINE_MAX_LEN}));
  
    resolve(null);
  });
}

function link(value, field = {}) {
  return new Promise(resolve => {
    if(field.isNull && !value.link) return resolve(null);
    if(value == null || !value.toString().length) return resolve(i18n.t('common.placeholder.inputSomething', {data1: field.displayName}));
    if (!LINK_REG.test(value.link)) return resolve(i18n.t('common.util.validator.linkTip'));
    // if (!/^https?/g.test(value)) return resolve('超链接请以http://或者https://开头');
  
    resolve(null);
  });
}

function customer(value, field = {}) {
  return new Promise((resolve, reject) => {
    // 先验证长度
    if(value != null && value.toString().length > SINGLE_LINE_MAX_LEN){
      return resolve(i18n.t('common.util.validator.maxLengthTip', {max: SINGLE_LINE_MAX_LEN}));
    }
    // 允许为空则不继续验证
    if(field.isNull) return resolve(null);
    // 不允许为空
    if(!value || value.toString().length == 0) return resolve(i18n.t('common.placeholder.inputSomething', {data1: field.displayName}));
    resolve(null);
  })
}

function extend(value, field = {}) {
  return new Promise((resolve, reject) => {
    // 允许为空则不继续验证
    if(field.isNull) return resolve(null);
    // 不允许为空
    if(!value || value.toString().length == 0) return resolve(i18n.t('common.placeholder.selectSomething', {0: field.displayName}));
    resolve(null);
  })
} 

function logistics(value, field = {}) {
  
  const isNull = field.isNull === 1;
  
  return new Promise(resolve => {
    
    const firstValue = value?.[0] || {}
    const companyId = firstValue?.company?.id
    const phone = firstValue?.phone
    const isSFExpress = companyId == 42
    
    if (isNull && isSFExpress && !_.isNil(phone) && !phone.trim()) {
      return resolve(i18n.t('common.util.validator.logisticsTip1'));
    }
    
    if (isNull) {
      resolve(null);
    }
    
    for (const { company, no, phone } of value) {
      
      if (!company || !company.id) {
        return resolve(i18n.t('common.placeholder.selectSomething', {0: i18n.t('common.base.logisticsCompany')}));
      }
      
      if (!no.trim()) {
        return resolve(i18n.t('common.placeholder.inputSomething', {data1: i18n.t('common.base.logisticsNo')}));
      }
      
      if(!_.isNil(phone) && !phone.trim()) {
        return resolve(i18n.t('common.util.validator.logisticsTip1'));
      }
      
      if(!_.isNil(phone) && phone.length !== 4) {
        return resolve(i18n.t('common.util.validator.logisticsTip2'));
      }
    }
    
    resolve(null);
    
  });
}
// js代码块
function jsCodeBlock(value, field = {}, origin = {}) {
  let {codeBlockConfig} = field.setting || {};
  return new Promise(async (resolve, reject) => {
    const codeContent = codeBlockConfig?.codeContent || '';
    const jsCode = await executeCode(codeContent, origin, field, true);
    const key = "errorMessage";
    if(jsCode){
      const obj = JSON.parse(jsCode);
      if (obj.hasOwnProperty(key)) {
        message.warning(obj[key]);
      }
      return resolve(obj[key] || null);
    }
    resolve(null);
  });
}

// 部门
function tag(value, field = {}) {
  return new Promise(resolve => {
    if (field.isNull === 1) return resolve(null);
    // 判断是否为空值
    let isEmpty = Array.isArray(value) ? (value.length <= 0 || !value[0].id) : !value?.id;

    if (!value || isEmpty) return resolve(i18n.t('common.placeholder.selectSomething', {0: field.displayName}));
    resolve(null);
  });
}

/**
 * 根据字段类型验证值
 * @param {*} value 值
 * @param {*} field 字段
 * @param {*} origin 原始数据
 * @param {String} mode 模式
 * @param {Function} changeStatus 改变状态方法
 * @param {Boolean} isSample 是否是简单模式 (简单模式的概念是单个字段的单个验证)
 * @returns Promise<message> 
 */
function validate(value, field, origin = {}, mode, changeStatus, isSample = true, formBuilderComponent = {}, cardType){
  let fn = RuleMap[field.formType];
  if(field.fieldName === 'catalogNum') return catalogNum(value, field);
  // 质保时长
  if(field.fieldName === ProductTypeFieldNameMappingEnum.QualityTime) return qualityTime(value, field);
  
  if(typeof fn == 'function') {
    // console.log('fn(value, field, origin, mode, changeStatus, isSample, formBuilderComponent,cardType)', fn(value, field, origin, mode, changeStatus, isSample, formBuilderComponent,cardType))
    return fn(value, field, origin, mode, changeStatus, isSample, formBuilderComponent, cardType)
  } 
  
  return Promise.resolve(null)
}

/** 
 * 创建远程验证方法
 * @param {function} api - 调用的api方法
 * @param {function} build - 参数构建方法
 * @param {number} delay - 延时, 默认500ms延时
 */
export function createRemoteValidate(api, build, delay = 500){
  let invoke = _.debounce(function(params, resolve, changeStatus){
    changeStatus(true);
    return api(params).then(res => {
      changeStatus(false);
      return resolve(res.error ? res.error : null);
    })
      .catch(err => console.error(err))
  }, delay);
  
  return function(value, field, changeStatus){
    let params = typeof build == 'function' ? build(value, field) : {};
    return new Promise(resolve => invoke(params, resolve, changeStatus))
  }
}

const Validator = {
  validate,
  createRemoteValidate
};




export default Validator;
